from django.shortcuts import render
from django.views import View
from django.http import JsonResponse
from django.conf import settings
from django.contrib.auth import login
from django_redis import get_redis_connection

from .models import OAuthQQUser
from users.models import User
from meiduo_mall.utils.secret import SecretOauth
from carts.utils import merge_cart_cookie_to_redis

from QQLoginTool.QQtool import OAuthQQ

import json,re

# Create your views here.
# 获取ＱＱ登陆扫码页面
class QQURLView(View):

    def get(self, request):
        # 1.提取参数
        # next　表示从哪个页面进入到的登陆页面，登陆成功后，就自动回到那个页面
        next = request.GET.get("next")

        # 2.校验参数

        # 3.业务数据处理－－获取ＱＱ登陆扫码页面
        # 创建OAuthQQ类的对象
        oauth = OAuthQQ(
            client_id=settings.QQ_CLIENT_ID,
            client_secret=settings.QQ_CLIENT_SECRET,
            redirect_uri=settings.QQ_REDIRECT_URI,
            state=next
        )

        # 获取ｑｑ地址
        url = oauth.get_qq_url()

        return JsonResponse({
            "code": 0,
            "errmsg": "ok",
            "login_url": url
        })


# 用户扫码登陆的回调处理
class QQUserView(View):

    def get(self, request):

        # 1.提取参数
        code = request.GET.get("code")

        # 2.校验参数
        if not code:
            return JsonResponse({"code": 400, "errmsg": "缺少code参数"})

        # 3.业务数据处理－－用户扫码登陆的回调处理
        # 3.1 获取openid
        try:
            oauth = OAuthQQ(
                client_id=settings.QQ_CLIENT_ID,
                client_secret=settings.QQ_CLIENT_SECRET,
                redirect_uri=settings.QQ_REDIRECT_URI,
                state=next
            )

            access_token = oauth.get_access_token(code)
            openid = oauth.get_open_id(access_token)

        except Exception as e:
            return JsonResponse({"code": 400, "errmsg": "用户qq身份验证失败"})

        # 3.2 判断用户是否绑定QQ账号 —— 把用户的美多账号和QQ的账号绑定
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)

        except OAuthQQUser.DoesNotExist as e:
            # 构建响应(未绑定) —— 需要把openid加密返回给前端
            # 加密openid
            auth = SecretOauth()
            access_token = auth.dumps({"openid": openid})

            # 注意: 这里一定不能返回 0 的状态码. 否则不能进行绑定页面
            return JsonResponse({"code": 300, "errmsg": "ok", "access_token": access_token})

        else:
            # 已绑定,返回响应
            # 状态保持
            # 根据user外键，获取对应的ｑｑ用户(user) user = qq_user.user
            login(request, qq_user.user)
            response = JsonResponse({"code": 0, "errmsg": "ok"})
            response.set_cookie("username", qq_user.user.username, max_age=14 * 24 *3600)
            return response

    def post(self, request):
        # 1.提取参数
        data = json.loads(request.body.decode())
        mobile = data.get("mobile")
        password = data.get("password")
        sms_code = data.get("sms_code")
        access_token = data.get("access_token")
        # 2.校验参数
        # 2.1　完整性校验
        if not all([mobile, password, sms_code, access_token]):
            return JsonResponse({"code": 400, "errmsg": "数据不完整"})

        # 2.2 约束校验
        if not re.match(r"^1[3,9]\d{9}$", mobile):
            return JsonResponse({"code": 400, "errmsg": "手机号格式错误"})
        if not re.match(r"^[0-9a-zA-Z]{8,20}$", password):
            return JsonResponse({"code": 400, "errmsg": "密码格式错误"})

        #2.3 业务性校验－短信验证码
        conn = get_redis_connection("verify_code") # 2号
        sms_code_from_redis = conn.get("sms_%s"%mobile)    # 返回 b""
        if not sms_code_from_redis:
            return JsonResponse({"code": 400, "errmsg": "短信验证码过期"})
        if sms_code_from_redis.decode() != sms_code:
            return JsonResponse({"code": 400, "errmsg": "短信验证码有误"})

        # 3.业务处理－－绑定用户接口
        # 3.1 获取openid
        auth = SecretOauth()
        openid_dict = auth.loads(access_token) # {"opendid": "dddddsadas"}
        if openid_dict is None:
            return JsonResponse({"code": 400, "errmsg": "access_token无效"})
        openid = openid_dict.get("openid")

        # 3.2 根据手机查找用户
        try:
            user = User.objects.get(mobile=mobile)
        except User.DoesNotExist as e:
            # 根据手机找不到用户－－用户未注册美多账号
            # 新建美多账号
            user = User.objects.create_user(
                username=mobile,
                mobile=mobile,
                password=password
            )
            OAuthQQUser.objects.create(
                user=user,  # 当前已注册的美多账号
                openid=openid
            )
        else:
            # 根据手机找到用户－－用户已注册美多账号
            # 验证密码
            if not user.check_password(password):
                return JsonResponse({"code": 400, "errmsg": "密码有误"})
            # 绑定ＱＱ
            OAuthQQUser.objects.create(
                user=user,
                openid=openid
            )

        login(request, user)
        response = JsonResponse({"code": 0, "errmsg": "ok"})
        # 合并购物车
        response = merge_cart_cookie_to_redis(request, response)

        response.set_cookie("username", user.username, max_age=24*14*3600)
        return response
